﻿Public Class LR1TransitionTable
    Implements IEnumerable(Of LR1TransitionTableRow)

    Private m_rows As List(Of LR1TransitionTableRow)
    Private m_statesMap As Dictionary(Of LR1State, Integer)

    Public Const AcceptStateIndex As Integer = -1

    Public Sub New()
        m_rows = New List(Of LR1TransitionTableRow)
        m_statesMap = New Dictionary(Of LR1State, Integer)
    End Sub

    Public Function AddOrFind(ByVal state As LR1State) As Integer
        Dim index As Integer = 0
        If m_statesMap.TryGetValue(state, index) Then
            Return index
        Else
            'need to add
            m_rows.Add(New LR1TransitionTableRow(state))
            index = m_rows.Count - 1

            'save the index in the row, used in foreach statements
            m_rows(index).Index = index
            m_statesMap.Add(state, index)
            Return index
        End If
    End Function

    Default Public ReadOnly Property Items(ByVal index As Integer) As LR1TransitionTableRow
        Get
            Return m_rows(index)
        End Get
    End Property

    Public ReadOnly Property Count() As Integer
        Get
            Debug.Assert(m_statesMap.Count = m_rows.Count)
            Return m_statesMap.Count
        End Get
    End Property

    Public Function GetEnumerator() As IEnumerator(Of LR1TransitionTableRow) Implements IEnumerable(Of LR1TransitionTableRow).GetEnumerator
        Return m_rows.GetEnumerator()
    End Function

    Private Function GetEnumerator1() As IEnumerator Implements IEnumerable.GetEnumerator
        Return m_rows.GetEnumerator()
    End Function
End Class


